<?php
/**
 * 获取db数据
 * @param string $name
 * @param array $cond
 * @param array $orderby
 * @param int $page
 * @param int $pagesize
 * @return array
 */
function db($name, $cond = [], $orderby = [], $page = 0, $pagesize = 0){
	$name = DB.$name.'.php';
	if(is_file($name)){
		$data = include $name;
		if($cond !== false) $data = arrWhere($data, $cond, $orderby, $page, $pagesize);
		return $data;
	}else{
		return [];
	}
}
/**
 * 保存db数据
 * @param string $name
 * @param array $data
 * @return bool
 */
function dbSave($name,$data){
	return save(DB.$name.'.php',$data);
}
/**
 * 删除db数据
 * @param string $name
 * @param array $cond
 * @param bool $index 是否重新索引
 * @return bool
 */
function dbDelete($name,$cond=[],$index=false){
	$path = DB.$name.'.php';
	if(is_file($path)){
		if($cond){
			$arr = db($name);
			if(gettype($arr) !== 'array') return false;
			$sel = arrWhere($arr,$cond);
			foreach ($sel as $k => $v) {
				unset($arr[$k]);
			}
			if($index)$arr = array_merge($arr);
			return dbSave($name,$arr);
		}
		return delFile(dbPath($name));
	}
	return false;
}
/**
 * 更新db数据
 * @param string $name
 * @param array $cond
 * @param array|bool $data
 * @return bool
 */
function dbUpdate($name,$cond,$data=false){
	$path = DB.$name.'.php';
	if(is_file($path)){
		$arr1 = db($name);
		if(gettype($arr1) !== 'array') $arr1 = [];
		if($data === false){
			foreach ($cond as $k => $v) {
				$arr1[$k] = $v;
			}
		}else{
			if(gettype($data) !== 'array') return false;
			$arr2 = arrWhere($arr1,$cond);
			foreach ($arr2 as $k => $v) {
				foreach ($data as $k1 => $v1) {
					$arr1[$k][$k1] = $v1;
				}
			}
		}
		return dbSave($name,$arr1);
	}
	return false;
}
/**
 * 插入db数据
 * @param string $name
 * @param array $data
 * @param bool $index 是否重新索引
 * @return bool
 */
function dbInsert($name,$data,$index=true){
	$path = DB.$name.'.php';
	if(is_file($path)){
		$arr = db($name);
		if(gettype($data) === 'string') return dbSave($name,$arr.$data);
		if($index){
			$arr[] = $data;
		}else{
			foreach ($data as $k => $v) {
				$arr[$k] = $v;
			}
		}
		return dbSave($name,$arr);
	}
	return false;
}
/**
 * 获取db数据路径
 * @param string $name
 * @return string
 */
function dbPath($name){
	return DB.$name.'.php';
}
/**
 * 数据库版本同步
 */
function dbSync($list){
	//递归遍历所有字段
	$forField = function($arr,$list)use(&$forField){
		foreach($list as $name => $value){
			if(isset($arr[$name])){
				if($value && is_array($value)) $arr[$name] = $forField($arr[$name],$value);
			}else{
				$arr[$name] = $value;
			}
		}
		return $arr;
	};
	$updateDb = function($arr,$list)use(&$forField){
		if($list['type'] == 'define-array' || $list['type'] == 'key-array'){
			foreach($arr as $k => $v){
				$arr[$k] = $forField($v,$list['value']);
			}
		}
		if($list['type'] == 'int-array'){
			foreach($list['value'] as $v){
				if(!in_array($v,$arr)) $arr[]=$v;
			}
		}
		if($list['type'] == 'array') $arr = $forField($arr,$list['value']);
		return $arr;
	};
	foreach ($list as $k => $v) {
		if(substr($k,0,1) == '#') continue;
		$dir = substr($k,0,1) == '@' ? 1 : 0;
		if($dir){
			$k = substr($k,1);
			if(is_dir(DB.$k)){
				if($v['type'] != 'files'){
					$filesList = glob(DB.$k.'/*', GLOB_NOSORT);
					foreach($filesList as $key => $path){
						$data = include $path;
						if($data){
							$data = $updateDb($data,$v);
							save($path,$data);
						}
					}
				}
			}
		}else{
			$data = db($k);
			$data = $updateDb($data,$v);
			dbSave($k,$data);
		}
	}
	$conf = db('conf');
	$conf['db']['version'] = $list['#version'];
	dbSave('conf',$conf);
}
/**
 * 检查是否已登录
 */
function checkLogin(){
	if(!LOGIN) jump('login');
}
/**
 * 删除前后端模板缓存
 */
function delCompile(){
	delFile(LIB.'admin/compile');
	delFile(TPLPATH.'compile');
}
/**
 * 删除正文里的文件
 * @param string $content 正文
 */
function delContentFiles($content){
	if($content){
		preg_match_all("/\[(img|file)\s+([^\s\]]+).*?\]/i", $content, $files);
		if (!empty($files)) {				
			foreach ($files[2] as $v) {if(is_file(ROOT.$v))unlink(ROOT.$v);}
		}
	}
}
/**
 * 设置扩展接口
 * @param string $title
 * @param string|function $html
 */
function hook($title,$html){
    global $hook;
    $hook[$title] = isset($hook[$title]) ? $hook[$title] : '';
    if($title === 'css'){
        $hook[$title][] = function()use($html){echo '<link rel="stylesheet" href="'.$html.'"/>';};
    }elseif($title === 'script'){
    	$html = function()use($html){echo '<script src="'.$html.'"></script>';};
       $hook[$title][] = eval($html);;
    }else{
    	if(gettype($html) == 'object'){
    		$hook[$title][] = $html;
    	}else{
    		$hook[$title][] = function()use($html){echo $html;};
    	}
    }
}
/**
 * 网站提示
 * @param string $text
 * @param string $url
 */
function prompt($text='',$url=false){
	$_SESSION['prompt']['text']=$text;
	$_SESSION['prompt']['url']=$url;
	jump(get(0) == 'admin' ? 'admin/prompt' : 'prompt');
}
/**
 * 检查更新
 * @return string|bool
 */
function checkUpdate(){
	$v = curl('https://xueluo.cn/api/getVersion');
	if($v){
		$v = type($v,'array');
		if(isset($v['data'])){
			if(V !== $v['data']) return $v['data'];
		}
	}
	return false;
}
/**
 * 根据文件列表压缩文件
 * @param string $path
 * @param string $pathName
 * @return string
 */
function sxs($list,$pathName=''){
	include_once LIB.'file.util.class.php';
	$util = new fileUtil();
	$str = "# 溯雪资源文件\nhttps://xueluo.cn\n------------------\n";
	foreach ($list as $v) {
		$rv = ROOT.$v;
		if(is_file($rv)){
			$content = str_replace(['@',"\r\n","\n"],['_@_','_@rn@_','_@n@_'],file_get_contents($rv));
			$str .= '[file '.$v.']'.$content."\n";
		}else{
			$str .= '[dir '.$v."]\n";
			$str .= sx($rv,false);
		}
	}
	$str = trim($str,"\n");
	$util->createFile($pathName,$str);
	return $str;
}
/**
 * 根据目录压缩文件
 * @param string $path
 * @param string $pathName
 * @return string
 */
function sx($path,$pathName=''){
	include_once LIB.'file.util.class.php';
	$util = new fileUtil();
	$list = glob($path.'/*', GLOB_NOSORT);
	$str = $pathName !== false ? "# 溯雪资源文件\nhttps://xueluo.cn\n------------------\n" : '';
	$confPath = $path.'/conf.php';
	if(is_file($confPath) && $pathName !== false){
		$conf = include $confPath;
		if(is_array($conf)){
			if(isset($conf['name'])) $str .= "# 名称：{$conf['name']}\n";
			if(isset($conf['intro'])) $str .= "# 简介：{$conf['intro']}\n";
			if(isset($conf['home'])) $str .= "# 主页：{$conf['home']}\n";
			if(isset($conf['author'])) $str .= "# 作者：{$conf['author']}\n";
			if(isset($conf['contact'])) $str .= "# 联系：{$conf['contact']}\n";
			if(isset($conf['version'])) $str .= "# 版本：{$conf['version']}\n";
			$str .= "------------------\n";
		}
	}
	foreach ($list as $v) {
		$vPath = substr($v,strlen(ROOT));
		if(is_file($v)){
			$content = str_replace(['@',"\r\n","\n"],['_@_','_@rn@_','_@n@_'],file_get_contents($v));
			$str .= '[file '.$vPath.']'.$content."\n";
		}else{
			$info = pathinfo($v);
			if($info['basename'] !== 'compile'){
				$str .= '[dir '.$vPath."]\n";
				$str .= sx($v,false);
			}
		}
	}
	if($pathName !== false) $str = trim($str,"\n");
	if($pathName) $util->createFile($pathName,$str);
	return $str;
}
/**
 * 解压文件
 * @param string $file
 * @param string $path
 * @return string
 */
function unsx($file, $path=ROOT){
	include_once LIB.'file.util.class.php';
	$util = new fileUtil();
	$content = strlen($file)<200 && is_file($file) ? file_get_contents($file) : $file;
	$content = explode("\n",$content);
	foreach ($content as $v) {
		if($v){
			preg_match('/^\[(dir|file)\s(.*?)\](.+?)$/', $v, $m);
			if($m){
				if($m[1] == 'dir'){
					$util->createDir($path.$m[2]);
				}elseif($m[1] == 'file'){
					$value = str_replace(['_@rn@_','_@n@_','_@_'],["\r\n","\n",'@'],$m[3]);
					$util->createFile($path.$m[2],$value);
				}
			}
		}
	}
}
/**
 * 获取模板列表
 * @return array
 */
function getTpl() {
	global $conf;
	$list = glob(ROOT.'tpl/*', GLOB_ONLYDIR|GLOB_NOSORT);
	$tpl = [];
	$tpl['list'] = [];
	$arr1 = $arr2 = [];
	$tpl['count'] = 0;
	if($list){
		foreach ($list as $name) {
			$name = substr($name, strrpos($name, '/') + 1);
			$tplPath = ROOT.'tpl/'.$name.'/conf.php';
			if(is_file($tplPath)){
				$tplConf = include $tplPath;
				if(isset($tplConf['name']) && isset($tplConf['intro'])){
					$tplConf['id'] = $name;
					$tplConf['icon'] = HOME.'tpl/'.$name.'/icon.png';
					if($conf['tpl'] == $name){
						$arr1[$name] = $tplConf;
					}else{
						$arr2[$name] = $tplConf;
					}
				}
			}
		}
		$tpl['list'] = $arr1+$arr2;
		$tpl['count'] = count($tpl['list']);
	}
	return $tpl;
}
/**
 * 获取扩展列表
 * @return array
 */
function getExt() {
	$list = glob(ROOT.'ext/*', GLOB_ONLYDIR|GLOB_NOSORT);
	$ext = [];
	$ext['list'] = [];
	$ext['installList'] = $ext['notInstallList'] = [];
	$ext['installCount'] = $ext['count'] = 0;
	$installExt = db('ext');
	if($list){
		foreach ($list as $name) {
			$name = substr($name, strrpos($name, '/') + 1);
			$extPath = EXT.$name.'/conf.php';
			if(is_file($extPath)){
				$extConf = include $extPath;
				if(isset($extConf['name']) && isset($extConf['intro'])){
					$extConf['id'] = $name;
					$extConf['icon'] = HOME.'ext/'.$name.'/icon.png';
					if(in_array($name,$installExt)){
						$ext['installList'][$name] = $extConf;
					}else{
						$ext['notInstallList'][$name] = $extConf;
					}
				}
			}
		}
		$ext['installCount'] = count($ext['installList']);
		$ext['list'] = $ext['installList']+$ext['notInstallList'];
		$ext['count'] = count($ext['list']);
	}
	return $ext;
}
/**
 * 文件删除
 */
function delFile($file) {return is_file($file) ? unlink($file) : FALSE;}
/**
 * 获取内存使用情况
 */
function getMemory(){
	return (int)((memory_get_usage() - $_SERVER['_memory_usage']) / 1024);
}
/**
 * 获取运行时间
 */
function getRunTime(){
	global $timeStart;
	return (float)substr(microtime(true) - $timeStart,0,6);
}
/**
 * 获取文章列表
 * @param array $cond
 * @param array $orderby
 * @param bool|string $url
 * @param int $page
 * @param int $pagesize
 * @return array
 */
function getArticle($cond = [], $orderby = [], $url = false, $page = 0, $pagesize = 0){
	global $articleList;
	$selList = arrWhere($articleList,$cond, $orderby);
	$arr1 = $arr2 = [];
	foreach ($selList as $k => $v) {
		$v['url'] = URL.$k;
		if($v['tag']){
			$list = [];
			$html = '';
			foreach($v['tag'] as $t){
				$a = '<a href="'.URL.'tag/'.$t.'">'.$t.'</a>';
				$html .= $a;
				$list[] = [
					'name' => $t,
					'url' => URL.'tag/'.$t,
					'html' => $a
				];
			}
			$v['tag'] = [
				'name' => implode(' ',$v['tag']),
				'html' => $html,
				'list' => $list
			];
		}else{
			$v['tag'] = [
				'name' => '',
				'html' => '',
				'list' => []
			];
		}
		if($v['top']){
			$arr1[$k] = $v;
		}else{
			$arr2[$k] = $v;
		}
	}
	$selList = $arr1+$arr2;
	$arr = [];
	$arr['count'] = count($selList);
	$arr['list'] = $pagesize ? arrPages($selList,$page, $pagesize) : $selList;
	if($url) $arr['paging'] = pages(URL.$url, $arr['count'], $page, $pagesize);
	return $arr;
}
/**
 * 重新格式化tag信息
 */
function tagInit(){
	dbSave('tag',getTag());
}
/**
 * 获取标签，如果传参，则返回该标签的文章列表
 * @param bool|string $name
 * @return array
 */
function getTag($name=false){
	global $articleList;
	if(!$articleList) return [];
	$arr = [];
	if($name){
		$name = urldecode($name);
		foreach ($articleList as $k=> $v) {
			if(in_array($name,$v['tag']))$arr[$k]=$v;
		}
	}else{
		foreach ($articleList as $k=> $v) {
			if($v['tag']){
				foreach ($v['tag'] as $vs) {
					$arr[$vs] = isset($arr[$vs]) ? ++$arr[$vs] : 1;
				}
			}
		}
	}
	return $arr;
}
/**
 * 获取访客列表
 * @param bool|string $url
 * @param int $page
 * @param int $pagesize
 * @return array
 */
function getVisit($url = false, $page = 0, $pagesize = 0){
	$visit = array_reverse(db('visit'));
	$todayStart = strtotime(date('Y-m-d'),time());
	$todayEnd = $todayStart + 86400;
	$todayCount=0;
	foreach ($visit as $k => $v) {
		if($v>$todayStart && $v<$todayEnd){
			$todayCount++;
		}
	}
	$arr = [];
	$arr['today'] = $todayCount;
	$arr['count'] = count($visit);
	$arr['list'] = arrPages($visit,$page, $pagesize);
	if($url) $arr['paging'] = pages(URL.$url, $arr['count'], $page, $pagesize);
	return $arr;
}
/**
 * 获取错误列表
 * @param array $cond
 * @param array $orderby
 * @param bool|string $url
 * @param int $page
 * @param int $pagesize
 * @return array
 */
function getError($cond = [], $orderby = [], $url = false, $page = 0, $pagesize = 0){
	$error = db('error',$cond,$orderby);
	$arr = [];
	$arr['count'] = count($error);
	$arr['list'] = arrPages($error,$page, $pagesize);
	if($url) $arr['paging'] = pages(URL.$url, $arr['count'], $page, $pagesize);
	return $arr;
}
/**
 * 重新格式化文章中的评论数
 * @param string $id
 */
function commentsInit($id){
	global $articleList;
	if(isset($articleList[$id])){
		$articleList[$id]['comments'] = count(db('comment/'.$id));
		dbSave('article',$articleList);
	}
}
/**
 * 获取评论
 * @param string $id
 * @param array $cond
 * @param array $orderby
 * @param bool|string $url
 * @param int $page
 * @param int $pagesize
 * @return array
 */
function getComment($id, $cond = [], $orderby = [], $url = false, $page = 0, $pagesize = 0){
	$comment = db('comment/'.$id);
	$comment = arrWhere($comment,$cond, $orderby);
	$arr = [];
	$arr['count'] = count($comment);
	$comment = array_reverse(arrTree($comment));
	$arr['list'] = arrPages($comment,$page, $pagesize);
	$arr['html'] = getCommentHtml($arr['list']);
	if($url) $arr['paging'] = pages(URL.$url, count($comment), $page, $pagesize);
	return $arr;
}
/**
 * 获取留言列表html
 * @param array $list
 * @return string
 */
function getCommentHtml($list){
	if(!$list) return '';
	$html = '<ul class="comment">';
	foreach ($list as $k => $v) {
		$html .= '<li><div class="comment-title"><span class="comment-'.(isset($v['admin'])&&$v['admin']?'admin ip-'.$v['id'].'">作者':'ip ip-'.$v['id'].'">'.(isset($v['username'])?$v['username']:$v['ip'])).'</span><span class="comment-time">'.dates($v['time']).'</span><span class="comment-reply" onclick="SX.reply('.$v['id'].');">回复</span>'.(LOGIN?'<a href="'.URL.'comment/delete/'.get(0).'/'.$v['id'].'" onclick="return SX.confirm(this,\'确实要删除吗？删除不可恢复！\')">删除</a>':'').'</div><div class="comment-content"><p>'.implode('</p><p>', explode("\r\n",$v['content'])).'</p></div>';
		if($v['child']){
			$html .= getCommentHtml($v['child']);
		}
		$html .='</li>';
	}
	$html .= '</ul>';
	return $html;
}
/**
 * 删除留言
 * @param string $path
 * @param bool|int $id
 */
function delComment($path,$id=false){
	$dbPath = DB.$path.'.php';
	if(is_file($dbPath)){
		include_once LIB.'file.util.class.php';
		$util = new fileUtil();
		if($id !== false){
			$arr = db($path,['pid'=>$id]);
			foreach ($arr as $key => $value) {
				delComment($path,$value['id']);
			}
			$conf = db('conf');
			$conf['comment']['count'] -= 1;
			dbDelete($path,['id'=>$id],true);
			dbSave('conf',$conf);
			//如果不存在留言，直接删除整个文件
			if(!db($path)) $util->delete($dbPath);
		}else{
			$util->delete($dbPath);
		}
	}
}
/**
 * 格式化链接
 * @return array
 */
function initLink($content){
	$link = trim($content);
	if(!$link) return [];
	$link = explode("\n", $link);
	$arr = [];
	foreach ($link as $v) {
		$a = preg_split('/\s+/',$v);
		$target = 0;
		$url = URL.$a[1];
		if(substr($a[0],0,1) == '>'){
			$target = 1;
			$a[0] = substr($a[0],1);
		}
		if(substr($a[0],0,1) == '!'){
			$a[0] = substr($a[0],1);
			$url = $a[1];
		}
		$arr[] = [
			'title' => $a[0],
			'url' => $url,
			'target' => $target
		];
	}
	return $arr;
}
?>